﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeartLess.GameObjects;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using HeartLess.Core;
using HeartLess.Managers;

namespace HeartLess.LevelData
{
    public class Level
    {

        private IList<Enemy> _enemies;
        private IList<Block> _blocks;
        private IList<Item> _modifiers;

        public const int UNIT_PIXEL_SIZE = 100;

        public const string THEME_ICE = "Ice";
        public const string THEME_HELL = "Hell";
        public const string THEME_JUNGLE = "Jungle";

        public Player Player
        {
            get;
            set;
        }

        public Texture2D StaticBackground
        {
            get;
            set;
        }

        public Texture2D MovingBackground
        {
            get;
            set;
        }

        public static AssetManager.SPRITES NORMAL_BLOCK;
        public static AssetManager.SPRITES END_BLOCK;

        public Level(String theme)
        {
            END_BLOCK = AssetManager.SPRITES.BLOCK_END;

            switch (theme)
            {

                case THEME_ICE:
                    NORMAL_BLOCK = AssetManager.SPRITES.BLOCK_NORMAL_ICE;
                    MovingBackground = AssetManager.GetSpriteTexture(AssetManager.SPRITES.MOVING_BACKGROUND_ICE);
                    StaticBackground = AssetManager.GetSpriteTexture(AssetManager.SPRITES.STATIC_BACKGROUND_ICE);
                    break;

                case THEME_JUNGLE:
                    NORMAL_BLOCK = AssetManager.SPRITES.BLOCK_NORMAL_JUNGLE;
                    MovingBackground = AssetManager.GetSpriteTexture(AssetManager.SPRITES.MOVING_BACKGROUND_JUNGLE);
                    StaticBackground = AssetManager.GetSpriteTexture(AssetManager.SPRITES.STATIC_BACKGROUND_JUNGLE);
                    break;

                case THEME_HELL:

                    break;
            }

            _blocks = new List<Block>();
            _enemies = new List<Enemy>();
            _modifiers = new List<Item>();
        }

        public static Vector2 getLocationFromGridPoint(Point gridPoint)
        {
            return new Vector2(gridPoint.X * Level.UNIT_PIXEL_SIZE,
                               (4-gridPoint.Y) * Level.UNIT_PIXEL_SIZE);
        }

        public void Update(GameTime gameTime)
        {
            Screen.FocusCameraOn(Player.Location);

            Player.Update(gameTime);

            foreach (Enemy enemy in _enemies)
            {
                enemy.Update(gameTime);
            }

            for (int i = _enemies.Count(); --i >= 0; )
            {
                if (_enemies[i].Dead)
                    _enemies.RemoveAt(i);
            }

            foreach (Item item in _modifiers)
            {
                item.Update(gameTime);
            }

            for (int i = _modifiers.Count(); --i >= 0; )
            {
                if (_modifiers[i].Dead)
                    _modifiers.RemoveAt(i);
            }

            foreach (Block block in _blocks)
            {
                block.Update(gameTime);
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            DrawBackground(spriteBatch);

            Player.Draw(spriteBatch);

            foreach (Enemy enemy in _enemies)
            {
                TryDraw(enemy, spriteBatch);
            }

            foreach (Item item in _modifiers)
            {
                item.Draw(spriteBatch);
            }

            foreach (Block block in _blocks)
            {
                TryDraw(block, spriteBatch);
            }
        }

        public void AddBlock(Block block)
        {
            _blocks.Add(block);
        }

        public void AddEnemy(Enemy enemy)
        {
            _enemies.Add(enemy);
        }

        public void AddModifier(Item modifier)
        {
            _modifiers.Add(modifier);
        }

        private void TryDraw(GameObject gameObject, SpriteBatch spriteBatch)
        {
            if (ObjectIsOnScreen(gameObject))
            {
                gameObject.Draw(spriteBatch);
            }
        }

        private void DrawBackground(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(StaticBackground, Screen.WINDOW_BOUNDS, Color.White);

            int offsetX = (int)(Player.Location.X / Screen.WINDOW_WIDTH) * Screen.WINDOW_WIDTH;
            int offsetX2 = offsetX + Screen.WINDOW_WIDTH;
            int offsetX3 = offsetX - Screen.WINDOW_WIDTH;

            //int offsetY = (int) (-Screen.WINDOW_HEIGHT - Player.Location.Y);
            //if (offsetY < Screen.WINDOW_HEIGHT / 2) offsetY = Screen.WINDOW_HEIGHT / 2;


            Rectangle bg1 = new Rectangle(offsetX, -Screen.WINDOW_HEIGHT, Screen.WINDOW_WIDTH, 2 * Screen.WINDOW_HEIGHT);
            Rectangle bg2 = new Rectangle(offsetX2, -Screen.WINDOW_HEIGHT,  Screen.WINDOW_WIDTH, 2 * Screen.WINDOW_HEIGHT);
            Rectangle bg3 = new Rectangle(offsetX3, -Screen.WINDOW_HEIGHT, Screen.WINDOW_WIDTH, 2 * Screen.WINDOW_HEIGHT);

            Screen.Draw(spriteBatch, bg1, MovingBackground);
            Screen.Draw(spriteBatch, bg2, MovingBackground);
            Screen.Draw(spriteBatch, bg3, MovingBackground);
        }

        private static bool ObjectIsOnScreen(GameObject gameObject)
        {
            return Screen.CameraBounds.Intersects(gameObject.Bounds);
        }

    }
}
